package com.yizhuoyan.his.serviceimpl.admin;

import com.yizhuoyan.his.ao.NoDrugChargeQueryAo;
import com.yizhuoyan.his.ao.NodrugChargeAddAo;
import com.yizhuoyan.his.ao.NodrugChargeModifyAo;
import com.yizhuoyan.his.dao.FinExpenseCategoryDao;
import com.yizhuoyan.his.dao.HosDepartmentDao;
import com.yizhuoyan.his.dao.HosNodrugDao;
import com.yizhuoyan.his.dto.HosNodrugDto;
import com.yizhuoyan.his.entity.FinExpenseCategoryEntity;
import com.yizhuoyan.his.entity.HosDepartmentEntity;
import com.yizhuoyan.his.entity.HosNodrugEntity;
import com.yizhuoyan.his.exception.HISDataExistsException;
import com.yizhuoyan.his.exception.HISDataNotExistsException;
import com.yizhuoyan.his.exception.HISIllegalParameterException;
import com.yizhuoyan.his.qco.HosNodrugQco;
import com.yizhuoyan.his.service.admin.NodrugChargeManageService;
import com.yizhuoyan.his.servicesupport.DatabaseIdGenerateSupportService;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.expr.NewArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 非药品收费项目管理服务
 * author：ZJH
 */
@Service
@Transactional
@Validated
@Slf4j
public class NodrugChargeManageServiceImpl implements NodrugChargeManageService {

    @Autowired
    HosNodrugDao hosNodrugDao;
    @Autowired
    HosDepartmentDao hosDepartmentDao;
    @Autowired
    FinExpenseCategoryDao finExpenseCategoryDao;
    @Autowired
    DatabaseIdGenerateSupportService idGenerateSupportService;
    @Override
    public HosNodrugEntity addNodrug(@NonNull @Valid NodrugChargeAddAo ao) throws Exception {
        log.trace("新增非药品收费项目，验证参数:{}", ao);

        String code = ao.getCode();
        long departmentId = Long.parseLong(ao.getDepartmentId());
        long expenseCategoryId = Long.parseLong(ao.getExpenseCategoryId());
        String name = ao.getName();
        String specification = ao.getSpecification();
        int unitPrice = Integer.parseInt(ao.getUnitPrice());

        checkId(departmentId, "执行科室id");
        checkId(expenseCategoryId, "所属费用科目id");

        log.trace("验证科室id:{}是否存在", departmentId);
        HosDepartmentEntity hosDepartmentEntity = hosDepartmentDao.selectById(departmentId);
        if (hosDepartmentEntity == null) {
            throw new HISDataNotExistsException("科室不存在");
        }

        log.trace("验证所属费用科目id:{}是否存在", expenseCategoryId);
        FinExpenseCategoryEntity finExpenseCategoryEntity = finExpenseCategoryDao.selectById(expenseCategoryId);
        if (finExpenseCategoryEntity == null) {
            throw new HISDataNotExistsException("所属费用科目不存在");
        }

        log.trace("验证code:{}的唯一性", code);
        if (hosNodrugDao.exists("code", code)) {
            throw new HISDataExistsException("该项目编码已存在");
        }

        HosNodrugEntity entity = new HosNodrugEntity();
        entity.setId(idGenerateSupportService.nextId());
        entity.setCode(code);
        entity.setName(name);
        entity.setSpecification(specification);
        entity.setUnitPrice(unitPrice);
        entity.setExpenseCategoryId(expenseCategoryId);
        entity.setDepartmentId(departmentId);
        entity.setCreateTime(LocalDateTime.now());

        log.trace("执行插入操作");
        hosNodrugDao.insert(entity);
        return entity;
    }

    @Override
    public void modifyNodrug(Long nodrugId, @NonNull @Valid NodrugChargeModifyAo ao) throws Exception {
        log.trace("修改非药品收费项目，验证参数：id={},修改数据={}", nodrugId, ao);

        checkId(nodrugId, "非药品收费项目id");
        HosNodrugEntity entity = hosNodrugDao.selectById(nodrugId);
        if (entity == null) {
            throw new HISDataNotExistsException("选定非药品收费项目不存在");
        }
        log.trace("验证code:{}的唯一性", ao.getCode());
        if (ao.getCode() != null && hosNodrugDao.exists("code", ao.getCode())) {
            throw new HISDataExistsException("该项目编码已存在");
        }

        Map<String, Object> map = new HashMap<>(8, 1);
        map.put("code", ao.getCode());
        map.put("name", ao.getName());
        map.put("specification", ao.getSpecification());
        map.put("unitPrice", ao.getUnitPrice());
        if (ao.getDepartmentId() != null) {
            map.put("departmentId", ao.getDepartmentId());
        }
        if (ao.getExpenseCategoryId() != null) {
            map.put("expenseCategoryId", ao.getExpenseCategoryId());
        }
        log.trace("执行更新，需要更新得字段是：{}", map);
        if (!map.isEmpty()) {
            hosNodrugDao.update(nodrugId, map);
        }
    }

    @Override
    public void removeNodrug(Long nodrugId) throws Exception {
        checkId(nodrugId, "非药品收费项目id");
        HosNodrugEntity entity = hosNodrugDao.selectById(nodrugId);
        if (entity == null) {
            throw new HISDataNotExistsException("指定非药品收费项目不存在");
        }
        log.trace("执行删除操作，删除id为{}", nodrugId);
        hosNodrugDao.delete(nodrugId);
    }

    @Override
    public List<HosNodrugDto> queryNodrug(@Valid NoDrugChargeQueryAo ao) throws Exception {
        log.trace("根据条件查询非药品收费项目，查询参数:{}", ao);
        HosNodrugQco hosNodrugQco = new HosNodrugQco();
        if (ao != null) {
            if (ao.getCode() != null && ao.getCode().trim() != null) {
                hosNodrugQco.setCode("%" + ao.getCode().trim() + "%");
            }
            if (ao.getName() != null && ao.getName().trim() != null) {
                hosNodrugQco.setName("%" + ao.getName().trim() + "%");
            }
            if (ao.getDepartmentId() != null) {
                hosNodrugQco.setDepartmentId(Long.parseLong(ao.getDepartmentId()));
            }
            if (ao.getExpenseCategoryId() != null) {
                hosNodrugQco.setExpenseCategoryId(Long.parseLong(ao.getExpenseCategoryId()));
            }
        }
        log.trace("执行查询操作");
        List<HosNodrugEntity> hosNodrugEntities = hosNodrugDao.selectByCondition(hosNodrugQco);
        List<HosNodrugDto> hosNodrugDtos = new LinkedList<>();
        FinExpenseCategoryEntity finExpenseCategoryEntity;
        HosDepartmentEntity hosDepartmentEntity;
        HosNodrugDto dto;

        log.trace("组装业务结果");
        for (HosNodrugEntity entity : hosNodrugEntities) {
            dto = HosNodrugDto.transform(entity);
            finExpenseCategoryEntity = finExpenseCategoryDao.selectById(entity.getExpenseCategoryId());
            hosDepartmentEntity = hosDepartmentDao.selectById(entity.getDepartmentId());
            dto.setExpenseCategoryName(finExpenseCategoryEntity.getName());
            dto.setDepartmentName(hosDepartmentEntity.getName());
            hosNodrugDtos.add(dto);
        }
        log.trace("返回查询结果");
        return hosNodrugDtos;
    }


    /**
     * 判断字符串id是否合法（合理转换，大小）
     *
     * @param id
     * @param idName
     */
    private void checkId(@NonNull Long id, String idName) {
        log.trace("判断id是否合法");
        if (id < 0) {
            throw new HISIllegalParameterException("参数" + idName + ":不合法");
        }
    }
}
